/*
**
**			Heroes IV
**	  Copyright 2001, The 3DO Company
**
**      adv_prison.cpp
*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_prison.h"

#include "adventure_ai.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_sounds.h"
#include "adv_object_type.h"
#include "ai_value.h"
#include "army.h"
#include "basic_dialog.h"
#include "creature.h"
#include "external_string.h"
#include "format_string.h"
#include "game_replace_keywords.h"
#include "hero.h"
#include "mouse_event.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "popup_window.h"
#include "replace_keywords.h"

namespace
{
	int const k_current_version = 1;

	int const k_current_map_version = 1;

	t_object_registration<t_adv_prison> k_registration( k_adv_object_prison );
}


/*
** Prison - holds hero.
*/
t_adv_prison::t_adv_prison( std::string const& source )
          : t_stationary_adventure_object( source ),
		    m_hero( new t_hero ),
			m_was_old_format( false )
{
}

// -------------------------------------------------------------------
// Army touched the prison. Release prisoner
// -------------------------------------------------------------------
void t_adv_prison::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                             t_direction direction, t_adventure_frame* frame )
{
	t_counted_ptr< t_adventure_map > map = frame->get_map();

	t_player* owner = army->get_owner();

	if (!owner) return;

	if (!owner->is_computer())
	{
		/*
		** Setup result dialog box.
		*/
		t_counted_ptr<t_basic_dialog> dialog_ptr = new t_basic_dialog ();
		std::string     text;

		text = replace_keywords( get_text("Initial"), m_hero.get() );

		dialog_ptr->set_text( text );
		dialog_ptr->add_ok_button();
		dialog_ptr->add_creature ( *m_hero, false );
		/*
		** Update frame.
		*/
		//frame->update_armies();
		frame->update();

		// Result dialog box.
		dialog_ptr->open();
		t_sound_cache music = get_music_playing();
		stop_music();
		get_dialog_sound( k_dialog_sound_thieves_guild )->play( get_sound_volume() );
		dialog_ptr->run_modal();
		play_music( music );
	}

    /*
    ** Add hero.  Add to creature array if possible.
    */
    if (army->get_creatures().can_add_hero())
    {
        army->get_creatures().add( m_hero ); //, 1 );
    }
    /*
    ** Or else create new army.
    */
    else	// TODO:  Should this be "else if ( player.can_create_army() )"? -- SCR 1/24/02
    {
	    t_army *		    temp_army = new t_army;
	    t_creature_array&   temp_creatures = temp_army->get_creatures();

        /*
        ** Create new army.
        ** Make army same color as player.
        */
	    temp_creatures.add ( m_hero );
	    temp_army->set_owner( army->get_owner_number() );
	    t_army * army = frame->create_army( this, temp_army, temp_army );

		army->trigger_events();
    }

    destroy();
}

// -------------------------------------------------------------------
// Get the save file version of the prison
// -------------------------------------------------------------------
int t_adv_prison::get_version() const
{
	return k_current_version;
}

// -------------------------------------------------------------------
// Read from save file
// -------------------------------------------------------------------
bool t_adv_prison::read( std::streambuf&					stream, 
					     t_qualified_adv_object_type const& type,
						 int								version )
{
	if ( version < 0 || version > k_current_version )
		return false;

	if ( version == 0 )
	{
		m_was_old_format = true;
		return true;
	}

	m_was_old_format = false;

	return m_hero->read( stream );
}

// -------------------------------------------------------------------
// Read from map file
// -------------------------------------------------------------------
bool t_adv_prison::read_from_map( std::streambuf&		stream,
									   t_progress_handler* )
{
	m_was_old_format = false; // Only applies to save files

	t_uint16 version = get< t_uint16 >( stream );

	if ( version > k_current_version )
		return false;

	if ( version == 0 )
		return true;

	return m_hero->read_from_map( stream );
}

// -------------------------------------------------------------------
// Write to save file
// -------------------------------------------------------------------
bool t_adv_prison::write( std::streambuf& stream ) const
{
	return m_hero->write( stream );
}

// -------------------------------------------------------------------
// Pass various notifications to the hero
// -------------------------------------------------------------------
bool t_adv_prison::preplacement( t_adventure_map& map, int pass )
{
	bool result_base = t_stationary_adventure_object::preplacement( map, pass );
	bool result_hero = m_hero->preplacement( map, pass, NULL );

	return result_base || result_hero;
}

void t_adv_prison::process_new_day()
{
	t_stationary_adventure_object::process_new_day();

	m_hero->process_new_day( NULL, false, NULL, 0);
}

void t_adv_prison::read_postplacement( t_adventure_map& map )
{
	t_stationary_adventure_object::read_postplacement( map );

	if ( m_was_old_format )
	{
		// Hero is not initialized
		m_hero->derandomize( map, NULL );
	}
	
	m_hero->read_postplacement( map );
}

float t_adv_prison::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	t_player const* player = army.get_owner();
	float swapped_value = 0.0f;

    if (army.can_add_hero())
	{
		t_owned_ptr<t_creature_array> new_army = ai_copy_of_creature_array( army );
	
		new_army->add( m_hero );

		swapped_value =	new_army->ai_value() - army.ai_value(); 	
	} 
	else
	{
		swapped_value = m_hero->ai_value();
	}
	return (1500 * player->get_material_value( k_gold )) + swapped_value;
}

extern t_external_string const k_text_hero_level;

void t_adv_prison::right_click( t_mouse_event const& event,
		                        t_adventure_frame* adventure_frame )
{
	t_skill_mastery information = get_information_level();

	if (information < k_mastery_basic)
	{
		t_stationary_adventure_object::right_click( event, adventure_frame );
		return;
	}

	t_window*						window;
	t_window*						modal_window = t_window::get_main_window();
	t_screen_point					point = event.screen_point;
	t_counted_ptr<t_basic_dialog>	dialog;
	std::string						text = get_text( "scouting" );

	point = modal_window->to_client( point );
	window = new t_popup_window( point, modal_window );
	window->set_cursor( adventure_frame->get_cursor( false ));
	dialog = new t_basic_dialog( window );
	dialog->add_creature( *m_hero, true );

	std::string class_text = k_text_hero_level;

	class_text = replace_keywords( class_text, "%level", format_string( "%i", m_hero->get_level() ));
	class_text = replace_keywords( class_text, "%class_name", m_hero->get_class_name() );
	text = replace_keywords( text, "%hero_class", class_text );
	text = replace_keywords( text, m_hero );
	dialog->set_text( text );
	dialog->open( t_screen_point(0,0), modal_window->get_client_rect() - point, 
		          true, k_align_top );
	window->fit_to_parent_rect();

}
